package com.unbox.generate.util;
import com.unbox.generate.entity.GenerateConfig;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.*;

@Component
public class Freemarker {

    @Autowired
    TableMapperUtil tableMapperUtil;

    /**
     * 生成mapperXml
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void mapperXml(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/resources/mapper/"+dataModel.get("sClassName")+"/";
        String fileName = dataModel.get("bClassName")+"Mapper"+".xml";
        generate(generateConfig,dataModel,"mapperxml.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成mapper
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void mapper(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/java/"+generateConfig.getRootPkg().replace(".", "/")+"/mapper/";
        String fileName = dataModel.get("bClassName")+"Mapper"+".java";
        generate(generateConfig,dataModel,"mapper.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成实体类
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void entity(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/java/"+generateConfig.getRootPkg().replace(".", "/")+"/entity/";
        String fileName = dataModel.get("bClassName")+".java";
        generate(generateConfig,dataModel,"entity.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成service接口
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void service(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/java/"+generateConfig.getRootPkg().replace(".", "/")+"/service/";
        String fileName = "I"+dataModel.get("bClassName")+"Service.java";
        generate(generateConfig,dataModel,"iservice.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成serviceImpl实现类
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void serviceImpl(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/java/"+generateConfig.getRootPkg().replace(".", "/")+"/service/impl/";
        String fileName = dataModel.get("bClassName")+"ServiceImpl.java";
        generate(generateConfig,dataModel,"serviceimpl.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成hystrix实现类
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void hystrix(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/java/"+generateConfig.getRootPkg().replace(".", "/")+"/hystrix/";
        String fileName = dataModel.get("bClassName")+"Hystrix.java";
        generate(generateConfig,dataModel,"hystrix.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成fegin实现类
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void fegin(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/java/"+generateConfig.getRootPkg().replace(".", "/")+"/fegin/";
        String fileName = dataModel.get("bClassName")+"Fegin.java";
        generate(generateConfig,dataModel,"fegin.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成controller实现类
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void controller(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/src/main/java/"+generateConfig.getRootPkg().replace(".", "/")+"/controller/";
        String fileName = dataModel.get("bClassName")+"Controller.java";
        generate(generateConfig,dataModel,"controller.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成apiJs接口调用
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void apiJs(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/vue/"+dataModel.get("sClassName")+"/js/";
        String fileName = "sys."+dataModel.get("sClassName")+".api.js";
        generate(generateConfig,dataModel,"apijs.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成vueList页面
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void vueList(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/vue/"+dataModel.get("sClassName")+"/list/";
        String fileName = "index.vue";
        generate(generateConfig,dataModel,"vuelist.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成vueList页面
     * @param generateConfig
     * @throws IOException
     * @throws TemplateException
     */
    public void vueEdit(GenerateConfig generateConfig) throws IOException, TemplateException {
        String cacheFile = System.getProperty("user.dir");
        // 第五步：创建一个模板使用的数据集，可以是pojo也可以是map。一般是Map。
        Map dataModel = tableMapperUtil.merge(generateConfig);
        String gearfileUrl = cacheFile+"/generator/vue/"+dataModel.get("sClassName")+"/edit/";
        String fileName = "index.vue";
        generate(generateConfig,dataModel,"vueedit.ftl", gearfileUrl, fileName);
    }

    /**
     * 生成公共类
     * @param generateConfig
     * @param dataModel
     * @param templateName
     * @param gearfileUrl
     * @param fileName
     * @throws IOException
     * @throws TemplateException
     */
    public void generate(GenerateConfig generateConfig, Map dataModel,String templateName, String gearfileUrl, String fileName) throws IOException, TemplateException {
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");
        configuration.setDefaultEncoding("UTF-8");
        Template template = configuration.getTemplate(templateName);
        File geanfile = new File(gearfileUrl);

        if (!geanfile.exists()) {
            geanfile.mkdirs();
        }

        // 第六步：创建一个Writer对象，一般创建一FileWriter对象，指定生成的文件名。
        Writer out = new FileWriter(new File(gearfileUrl+ fileName));

        // 第七步：调用模板对象的process方法输出文件。
        template.process(dataModel, out);

        // 第八步：关闭流
        out.close();
    }
}
